home *** CD-ROM | disk | FTP | other *** search
- USES CRT;
-
- {
- Here is my DRIVES routine again to return all valid drive letters on a
- PC. This is a fix from the last version which incorrectly addressed
- the local variables and wound up hosing memory. I also added some
- extensive comments for readability. Enjoy! }
-
- {*****************************************************************************
- * Function ...... Drives
- * Purpose ....... To return a string containing the valid drives for the
- * current system.
- * Parameters .... None
- * Returns ....... A string of the valid drive letters.
- * Notes ......... Rather than changing to each drive to see if it exists, we
- * can instead call DOS Function 26h - Parse a file name.
- * If the file name is invalid (eg, F:), then DOS will say
- * so. So, by testing each drive letter as a file name,
- * DOS will tell us which are good and which are bad!
- * Author ........ Martin Richardson
- * Date .......... August 6, 1993
- * Update ........ 02-01-94: Corrected problem where local VAR variables were
- * not being used, but a random memory location was
- * instead!
- * : Added comments for clarity.
- *****************************************************************************}
- FUNCTION Drives: STRING; ASSEMBLER;
- VAR
- DriveInfo: ARRAY[1..2] OF CHAR;
- Buffer: ARRAY[1..40] OF CHAR;
- DriveString: ARRAY[1..25] OF CHAR;
- ASM
- PUSH SI { Save Important Registers }
- PUSH DI
- PUSH ES
- PUSH DS
-
- MOV SI, SS { The Stack Segment (SS) points to the }
- MOV DS, SI { VAR's above. Point DS to it... }
- PUSH DS
- POP ES { ...and ES as well. }
-
- LEA SI, DriveInfo { DS:SI - Where we test each drive letter }
- LEA DI, Buffer { ES:DI - FCB Buffer }
- LEA BX, DriveString{ DS:BX - Our resultant string }
-
- MOV BYTE PTR [SI], '@' { The character before 'A' }
- XOR CX, CX { Zero out CX }
-
- @Scan:
- INC BYTE PTR [SI] { Next Drive Letter }
- MOV BYTE PTR [SI+1], ':'
- MOV AX, $2906 { DOS Function 29h - Parse Filename }
- INT 21h { DS:SI - String to be parsed }
- { ES:DI - FCB }
- LEA SI, DriveInfo { DS:SI }
- CMP AL, $FF{ AL = FFh if function fails (invalid }
- JE @NotValid { drive letter) }
-
- INC CX { Add one more to our string length... }
- PUSH CX { ...and save it. }
- MOV CL, BYTE PTR DS:[SI] { Grab the valid drive letter... }
- MOV [BX], CL { ...and stuff it into our result }
- INC BX { Next position in result string }
- POP CX { Get our length counter back }
-
- @NotValid:
- CMP BYTE PTR [SI], 'Z' { Did we go through all letters? }
- JNE @Scan { Nope, so next letter }
-
- LEA SI, DriveString{ Store DriveString to #Result }
- LES DI, @Result
- INC DI
- REP MOVSB
-
- XCHG AX, DI { This is the only way to store the }
- MOV DI, WORD PTR @Result { length that I can get to work. }
- SUB AX, DI
- DEC AX
- STOSB
-
- POP DS { Restore Important Registers }
- POP ES
- POP DI
- POP SI
- END;
-
- function DriveValid(Drive: Char): Boolean; assembler;
- asm
- mov ah, 19h { Select DOS function 19h }
- int 21h { Call DOS for current disk drive }
- mov bl, al { Save drive code in bl }
- mov al, Drive { Assign requested drive to al }
- sub al, 'A' { Adjust so A:=0, B:=1, etc. }
- mov dl, al { Save adjusted result in dl }
- mov ah, 0eh { Select DOS function 0eh }
- int 21h { Call DOS to set default drive }
- mov ah, 19h { Select DOS function 19h }
- int 21h { Get current drive again }
- mov cx, 0 { Preset result to False }
- cmp al, dl { Check if drives match }
- jne @@1 { Jump if not--drive not valid }
- mov cx, 1 { Preset result to True }
- @@1:
- mov dl, bl { Restore original default drive }
- mov ah, 0eh { Select DOS function 0eh }
- int 21h { Call DOS to set default drive }
- xchg ax, cx { Return function result in ax }
- end;
-
- BEGIN
- Clrscr;
- Writeln(Drives);
- END.